package com.matrix;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

@Slf4j
public class ZipUtil {

    /**
     * @param srcFiles 需压缩的文件路径及文件名
     * @param desFile  保存的文件名及路径
     * @return 如果压缩成功返回true
     */
    public static boolean zipCompress(String[] srcFiles, String desFile, String replacePath) {
        boolean isSuccessful = false;

        String[] fileNames = new String[srcFiles.length];
        System.arraycopy(srcFiles, 0, fileNames, 0, srcFiles.length);
        ZipOutputStream zos = null;
        BufferedInputStream bis = null;
        try {
            CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(desFile), new CRC32());
            zos = new ZipOutputStream(cos);
            String entryName;

            for (int i = 0; i < fileNames.length; i++) {
                entryName = fileNames[i].replace(replacePath + File.separator, "");

                // 创建Zip条目
                ZipEntry entry = new ZipEntry(entryName);
                zos.putNextEntry(entry);

                bis = new BufferedInputStream(new FileInputStream(srcFiles[i]));

                IOUtils.copy(bis, zos);
                bis.close();
                zos.closeEntry();
            }

            zos.flush();
            isSuccessful = true;
            log.info("size of " + desFile + " is " + getFormatSize(FileUtils.sizeOf(new File(desFile))));
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } finally {
            IOUtils.closeQuietly(zos);
        }

        return isSuccessful;
    }

    private static String getFormatSize(double size) {
        double kiloByte = size/1024;
        if(kiloByte < 1) {
            return size + "Byte(s)";
        }

        double megaByte = kiloByte/1024;
        if(megaByte < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
        }

        double gigaByte = megaByte/1024;
        if(gigaByte < 1) {
            BigDecimal result2  = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
        }

        double teraBytes = gigaByte/1024;
        if(teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
        }
        BigDecimal result4 = new BigDecimal(teraBytes);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
    }

}
